Skip to content

fix(smart_holder): keep void-cast semantics in from_unique_ptr - #6163

Merged
rwgk merged 5 commits into
pybind:masterfrom
henryiii:fix/smart-holder-unique-ptr-shared-from-this
Oct 5, 2026
Merged

rwgk merged 5 commits into
pybind:masterfrom
henryiii:fix/smart-holder-unique-ptr-shared-from-this

Conversation

@henryiii

@henryiii henryiii commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

🤖 AI text below 🤖

smart_holder::from_unique_ptr() always built the owning shared_ptr from a T *. This connects the std::enable_shared_from_this machinery to the holder control block. For trampoline (alias) types, shared_from_this() must not access this control block, because the resulting shared_ptr does not keep the Python object alive.

The void_cast_raw_ptr flag in detail/init.h was made ineffective by #5836, which changed the second parameter of from_unique_ptr() into a multiple-inheritance subobject pointer. As a result, a factory that returns a unique_ptr to a trampoline lost the guard, and the Python override could disappear silently.

from_unique_ptr() now has an explicit void_cast_raw_ptr parameter. When it is true, the raw pointer is cast to void * before constructing the owning shared_ptr. A shared_ptr<void> constructed from a T * would still connect the enable_shared_from_this machinery to its control block; converting an existing shared_ptr<T> to shared_ptr<void> is also too late. The multiple-inheritance behavior does not change.

This restores the ownership safeguard introduced in #3023. The holder's internal control block cannot retain the Python trampoline without creating a reference cycle that Python's garbage collector cannot detect. shared_from_this() initially throws bad_weak_ptr, but remains available once C++ holds a separate shared_ptr that retains the Python trampoline.

Fixes item 4 of #6159.

Suggested changelog entry:

  • Fixed py::init() factories returning a std::unique_ptr to a trampoline incorrectly exposing the holder's control block to shared_from_this().

@rwgk

rwgk commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

@henryiii I'm looking at this now. I'll merge master before I do my full review.

@rwgk
rwgk merged commit e0cd29d into pybind:master Oct 5, 2026
84 checks passed
@rwgk
rwgk deleted the fix/smart-holder-unique-ptr-shared-from-this branch October 5, 2026 04:04
@github-actions github-actions Bot added the needs changelog Possibly needs a changelog entry label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs changelog Possibly needs a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants